﻿namespace Test.Unit
{
    using System;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    using Moq;

    using ClientRouting;
    using ClientRouting.Transport;

    [TestClass]
    public class RouterTest
    {
        const int NumberOfServices = 5;

        RouterImpl<Service> _router;

        Mock<Service> _availableService;
        Mock<Service> _deadService;
        Mock<Connector<Service>> _availableConnector;
        Mock<Connector<Service>> _deadConnector;

        [TestInitialize]
        public void SetUp()
        {
            _router = new RouterImpl<Service>();

            _availableService = new Mock<Service>();
            _deadService = new Mock<Service>();
            
            _availableConnector = new Mock<Connector<Service>>();
            _deadConnector = new Mock<Connector<Service>>();

            _availableService.Setup(x => x.IsOnline()).Returns(true);
            _availableConnector.SetupGet(x => x.Proxy).Returns(_availableService.Object);

            _deadService.Setup(x => x.IsOnline()).Returns(false);
            _deadConnector.SetupGet(x => x.Proxy).Returns(_deadService.Object);
        }

        [TestMethod]
        public void OnRegisterCall_ServiceAvailability_ShouldBeChecked()
        {
            var t = _availableConnector.Object.Proxy.IsOnline();

            _router.Register(_availableConnector.Object);
            _availableService.Verify(x => x.IsOnline(), Times.AtLeastOnce());
        }

        [TestMethod]
        [ExpectedException(typeof(ClientRoutingException))]
        public void CannotRegisterAnOfflineService()
        {
            _router.Register(_deadConnector.Object);
        }

        [TestMethod]
        [ExpectedException(typeof(ClientRoutingException))]
        public void CannotRegister2TimesTheSameConnector()
        {
            _availableConnector.Setup(x => x.Equal(It.IsAny<Connector<Service>>())).Returns(true);

            _router.Register(_availableConnector.Object);
            _router.Register(_availableConnector.Object);
        }

        [TestMethod]
        public void CanCallFirstAvailableWithAnOnlineService()
        {
            _router.Register(_availableConnector.Object);
            Assert.IsTrue(_router.FirstAvailable.IsOnline());
        }
    }
}
